package com.kktoolbox.engine;

import com.kktoolbox.entity.DecumentSearchResult;
import com.kktoolbox.model.SearchProgressCallback;
import com.kktoolbox.utils.DocumentUtils;

// Apache POI imports for Word document processing
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

/**
 * Word文档搜索引擎核心类
 * 
 * @author KK-Toolbox
 * @version 1.0.0
 * @since 2025-01-01
 */
public class WordSearchEngine extends AbstractDocumentSearchEngine {
    
    /** 支持的Word文档扩展名 */
    private static final String DOC_EXTENSION = "doc";
    private static final String DOCX_EXTENSION = "docx";

    @Override
    protected String getDocumentType() {
        return "Word";
    }
    
    @Override
    protected boolean isSupportedFile(File file) {
        return DocumentUtils.hasExtension(file, DOC_EXTENSION) || 
               DocumentUtils.hasExtension(file, DOCX_EXTENSION);
    }
    
    @Override
    protected boolean containsText(File file, String searchText) {
        String extractedText = extractTextFromWord(file);
        if (extractedText == null || extractedText.trim().isEmpty()) {
            return false;
        }
        
        // 不区分大小写的文本匹配
        return DocumentUtils.containsTextIgnoreCase(extractedText, searchText);
    }

    /**
     * 从Word文件中提取文本内容
     * 
     * <p>根据文件扩展名自动选择合适的提取方法。
     * 支持.doc和.docx两种格式。</p>
     * 
     * @param file Word文件
     * @return 提取的文本内容，如果提取失败则返回null
     */
    private String extractTextFromWord(File file) {
        if (!DocumentUtils.isReadableFile(file)) {
            logger.warn("Word文件不可读: {}", DocumentUtils.getAbsolutePath(file));
            return null;
        }
        
        try {
            String fileName = file.getName().toLowerCase();
            if (fileName.endsWith("." + DOCX_EXTENSION)) {
                return extractTextFromDOCX(file);
            } else if (fileName.endsWith("." + DOC_EXTENSION)) {
                return extractTextFromDOC(file);
            } else {
                logger.warn("不支持的Word文件格式: {}", DocumentUtils.getAbsolutePath(file));
                return null;
            }
        } catch (Exception e) {
            logger.error("提取Word文本时发生错误: {} - {}", 
                        DocumentUtils.getAbsolutePath(file), e.getMessage());
            return null;
        }
    }

    /**
     * 从DOCX文件中提取文本内容
     * 
     * <p>提取Word 2007+格式文档的文本内容，包括段落和表格。</p>
     * 
     * @param docxFile DOCX文件
     * @return 提取的文本内容
     * @throws IOException 如果文件读取失败
     */
    private String extractTextFromDOCX(File docxFile) throws IOException {
        StringBuilder textBuilder = new StringBuilder();
        
        try (FileInputStream fis = new FileInputStream(docxFile);
             XWPFDocument document = new XWPFDocument(fis)) {
            
            // 提取段落文本
            List<XWPFParagraph> paragraphs = document.getParagraphs();
            for (XWPFParagraph paragraph : paragraphs) {
                String paragraphText = paragraph.getText();
                if (paragraphText != null && !paragraphText.trim().isEmpty()) {
                    textBuilder.append(paragraphText).append("\n");
                }
            }
            
            // 提取表格文本
            List<XWPFTable> tables = document.getTables();
            for (XWPFTable table : tables) {
                for (XWPFTableRow row : table.getRows()) {
                    for (XWPFTableCell cell : row.getTableCells()) {
                        String cellText = cell.getText();
                        if (cellText != null && !cellText.trim().isEmpty()) {
                            textBuilder.append(cellText).append(" ");
                        }
                    }
                    textBuilder.append("\n");
                }
            }
            
            String extractedText = textBuilder.toString();
            logger.debug("成功提取DOCX文本，文件: {}, 文本长度: {} 字符", 
                        DocumentUtils.getAbsolutePath(docxFile), extractedText.length());
            
            return extractedText;
            
        } catch (IOException e) {
            logger.error("读取DOCX文件失败: {} - {}", 
                        DocumentUtils.getAbsolutePath(docxFile), e.getMessage());
            throw e;
        }
    }

    /**
     * 从DOC文件中提取文本内容
     * 
     * <p>提取Word 97-2003格式文档的文本内容。</p>
     * 
     * @param docFile DOC文件
     * @return 提取的文本内容
     * @throws IOException 如果文件读取失败
     */
    private String extractTextFromDOC(File docFile) throws IOException {
        try (FileInputStream fis = new FileInputStream(docFile);
             HWPFDocument document = new HWPFDocument(fis)) {
            
            WordExtractor extractor = new WordExtractor(document);
            String extractedText = extractor.getText();
            
            logger.debug("成功提取DOC文本，文件: {}, 文本长度: {} 字符", 
                        DocumentUtils.getAbsolutePath(docFile), 
                        extractedText != null ? extractedText.length() : 0);
            
            return extractedText;
            
        } catch (IOException e) {
            logger.error("读取DOC文件失败: {} - {}", 
                        DocumentUtils.getAbsolutePath(docFile), e.getMessage());
            throw e;
        }
    }

    /**
     * 获取Word文档的页数
     * 
     * <p>获取Word文档的页数信息。注意：页数统计可能不够精确，
     * 特别是对于包含复杂格式的文档。</p>
     * 
     * @param wordFile Word文件
     * @return Word文档的页数，如果无法获取则返回0
     */
    public int getPageCount(File wordFile) {
        if (!DocumentUtils.isReadableFile(wordFile)) {
            return 0;
        }
        
        try {
            String fileName = wordFile.getName().toLowerCase();
            if (fileName.endsWith("." + DOCX_EXTENSION)) {
                return getPageCountFromDOCX(wordFile);
            } else if (fileName.endsWith("." + DOC_EXTENSION)) {
                return getPageCountFromDOC(wordFile);
            } else {
                logger.warn("不支持的Word文件格式: {}", DocumentUtils.getAbsolutePath(wordFile));
                return 0;
            }
        } catch (Exception e) {
            logger.error("获取Word页数时发生错误: {} - {}", 
                        DocumentUtils.getAbsolutePath(wordFile), e.getMessage());
            return 0;
        }
    }

    /**
     * 获取DOCX文档的页数
     */
    private int getPageCountFromDOCX(File docxFile) throws IOException {
        try (FileInputStream fis = new FileInputStream(docxFile);
             XWPFDocument document = new XWPFDocument(fis)) {
            
            // DOCX格式中页数信息不容易直接获取，这里返回段落数作为近似值
            return document.getParagraphs().size();
        }
    }

    /**
     * 获取DOC文档的页数
     */
    private int getPageCountFromDOC(File docFile) throws IOException {
        try (FileInputStream fis = new FileInputStream(docFile);
             HWPFDocument document = new HWPFDocument(fis)) {
            
            // DOC格式中也难以精确获取页数，返回段落数作为近似值
            return document.getRange().numParagraphs();
        }
    }
}